Skip to content

Commit aae3575

Browse files
authored
[Wasm GC] Fix inlining + non-nullable locals (#3945)
We don't need to assign a zero value for such locals (and we can't, as no default value exists for them). Fixes #3944
1 parent 28e88b9 commit aae3575

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

src/passes/Inlining.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,16 @@ doInlining(Module* module, Function* into, const InliningAction& action) {
292292
// Zero out the vars (as we may be in a loop, and may depend on their
293293
// zero-init value
294294
for (Index i = 0; i < from->vars.size(); i++) {
295+
auto type = from->vars[i];
296+
if (type.isRef() && !type.isNullable()) {
297+
// Non-nullable locals do not need to be zeroed out. They have no zero
298+
// value, and by definition should not be used before being written to, so
299+
// any value we set here would not be observed anyhow.
300+
continue;
301+
}
295302
block->list.push_back(
296303
builder.makeLocalSet(updater.localMapping[from->getVarIndexBase() + i],
297-
LiteralUtils::makeZero(from->vars[i], *module)));
304+
LiteralUtils::makeZero(type, *module)));
298305
}
299306
// Generate and update the inlined contents
300307
auto* contents = ExpressionManipulator::copy(from->body, *module);

test/lit/passes/inlining-gc.wast

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
2+
;; RUN: wasm-opt %s --inlining --enable-gc-nn-locals -all -S -o - | filecheck %s
3+
4+
(module
5+
;; CHECK: (func $caller-nullable
6+
;; CHECK-NEXT: (local $0 funcref)
7+
;; CHECK-NEXT: (block $__inlined_func$target-nullable
8+
;; CHECK-NEXT: (local.set $0
9+
;; CHECK-NEXT: (ref.null func)
10+
;; CHECK-NEXT: )
11+
;; CHECK-NEXT: (nop)
12+
;; CHECK-NEXT: )
13+
;; CHECK-NEXT: )
14+
(func $caller-nullable
15+
;; Call a function with a nullable local. After the inlining there will
16+
;; be a new local in this function for the use of the inlined code, and also
17+
;; we assign the null value to that local in the inlined block (which does
18+
;; not matter much here, but in general if we had a loop that the inlined
19+
;; block was inside of, that would be important to get the right behavior).
20+
(call $target-nullable)
21+
)
22+
23+
(func $target-nullable
24+
(local $1 (ref null func))
25+
)
26+
27+
;; CHECK: (func $caller-non-nullable
28+
;; CHECK-NEXT: (local $0 (ref func))
29+
;; CHECK-NEXT: (block $__inlined_func$target-non-nullable
30+
;; CHECK-NEXT: (nop)
31+
;; CHECK-NEXT: )
32+
;; CHECK-NEXT: )
33+
(func $caller-non-nullable
34+
;; Call a function with a non-nullable local. After the inlining there will
35+
;; be a new local in this function for the use of the inlined code. We do not
36+
;; need to zero it out (such locals cannot be used before being set anyhow, so
37+
;; no zero is needed; and we cannot set a zero anyhow as none exists for the
38+
;; type).
39+
(call $target-non-nullable)
40+
)
41+
42+
(func $target-non-nullable
43+
(local $1 (ref func))
44+
)
45+
)

0 commit comments

Comments
 (0)