Skip to content

Commit 8e0f19f

Browse files
authored
[StackSwitching] Avoid casting continuations in type-refining-gufa (#8037)
That pass can infer types in places that require casts.
1 parent f6fd861 commit 8e0f19f

2 files changed

Lines changed: 93 additions & 2 deletions

File tree

src/passes/TypeRefining.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ struct TypeRefining : public Pass {
209209
if (!fields[i].type.isExact()) {
210210
gufaType = gufaType.withInexactIfNoCustomDescs(module->features);
211211
}
212+
// Do not use the GUFA type if it is a continuation, as we cannot add
213+
// casts to fix up issues later.
214+
if (gufaType.isContinuation()) {
215+
continue;
216+
}
212217
infos[i] = LUBFinder(gufaType);
213218
}
214219
}

test/lit/passes/type-refining-gufa-exact.wast

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
;; Check that we don't refine in ways that might require invalid exact casts
44
;; when custom descriptors is disabled.
55

6-
;; RUN: wasm-opt %s -all --closed-world --preserve-type-order \
6+
;; RUN: foreach %s %t wasm-opt -all --closed-world --preserve-type-order \
77
;; RUN: --type-refining-gufa -S -o - | filecheck %s
88

9-
;; RUN: wasm-opt %s -all --disable-custom-descriptors --closed-world --preserve-type-order \
9+
;; RUN: foreach %s %t wasm-opt -all --disable-custom-descriptors --closed-world --preserve-type-order \
1010
;; RUN: --type-refining-gufa -S -o - | filecheck %s --check-prefix=NO_CD
1111

1212
(module
@@ -78,3 +78,89 @@
7878
)
7979
)
8080
)
81+
82+
;; Avoid casting continuations.
83+
(module
84+
(rec
85+
;; CHECK: (rec
86+
;; CHECK-NEXT: (type $func (func))
87+
;; NO_CD: (rec
88+
;; NO_CD-NEXT: (type $func (func))
89+
(type $func (func))
90+
;; CHECK: (type $cont (cont $func))
91+
;; NO_CD: (type $cont (cont $func))
92+
(type $cont (cont $func))
93+
;; CHECK: (type $struct (struct (field (ref $cont))))
94+
;; NO_CD: (type $struct (struct (field (ref $cont))))
95+
(type $struct (struct (field (ref $cont))))
96+
)
97+
98+
;; CHECK: (func $nop (type $func)
99+
;; CHECK-NEXT: (nop)
100+
;; CHECK-NEXT: )
101+
;; NO_CD: (func $nop (type $func)
102+
;; NO_CD-NEXT: (nop)
103+
;; NO_CD-NEXT: )
104+
(func $nop (type $func)
105+
(nop)
106+
)
107+
108+
;; CHECK: (func $trap (type $3) (result (ref $cont))
109+
;; CHECK-NEXT: (unreachable)
110+
;; CHECK-NEXT: )
111+
;; NO_CD: (func $trap (type $3) (result (ref $cont))
112+
;; NO_CD-NEXT: (unreachable)
113+
;; NO_CD-NEXT: )
114+
(func $trap (result (ref $cont))
115+
(unreachable)
116+
)
117+
118+
;; CHECK: (func $make (type $4)
119+
;; CHECK-NEXT: (drop
120+
;; CHECK-NEXT: (struct.new $struct
121+
;; CHECK-NEXT: (cont.new $cont
122+
;; CHECK-NEXT: (ref.func $nop)
123+
;; CHECK-NEXT: )
124+
;; CHECK-NEXT: )
125+
;; CHECK-NEXT: )
126+
;; CHECK-NEXT: (drop
127+
;; CHECK-NEXT: (struct.new $struct
128+
;; CHECK-NEXT: (call $trap)
129+
;; CHECK-NEXT: )
130+
;; CHECK-NEXT: )
131+
;; CHECK-NEXT: )
132+
;; NO_CD: (func $make (type $4)
133+
;; NO_CD-NEXT: (drop
134+
;; NO_CD-NEXT: (struct.new $struct
135+
;; NO_CD-NEXT: (cont.new $cont
136+
;; NO_CD-NEXT: (ref.func $nop)
137+
;; NO_CD-NEXT: )
138+
;; NO_CD-NEXT: )
139+
;; NO_CD-NEXT: )
140+
;; NO_CD-NEXT: (drop
141+
;; NO_CD-NEXT: (struct.new $struct
142+
;; NO_CD-NEXT: (call $trap)
143+
;; NO_CD-NEXT: )
144+
;; NO_CD-NEXT: )
145+
;; NO_CD-NEXT: )
146+
(func $make
147+
;; Make the struct twice, once with a proper continuation, and once with a
148+
;; call to a function that GUFA infers a trap in. The latter would usually
149+
;; be fixed up, allowing the struct field to be refined to be exact, but a cast is not
150+
;; valid on a continuation, so we must avoid refining this struct to have an
151+
;; exact field.
152+
(drop
153+
(struct.new $struct
154+
(cont.new $cont
155+
(ref.func $nop)
156+
)
157+
)
158+
)
159+
(drop
160+
(struct.new $struct
161+
(call $trap)
162+
)
163+
)
164+
)
165+
)
166+

0 commit comments

Comments
 (0)