summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/RedundantSetElimination.cpp9
-rw-r--r--test/lit/passes/rse-gc.wast15
2 files changed, 22 insertions, 2 deletions
diff --git a/src/passes/RedundantSetElimination.cpp b/src/passes/RedundantSetElimination.cpp
index 8b0914ecf..ccf6e6ac2 100644
--- a/src/passes/RedundantSetElimination.cpp
+++ b/src/passes/RedundantSetElimination.cpp
@@ -184,14 +184,19 @@ struct RedundantSetElimination
if (block.get() == entry) {
// params are complex values we can't optimize; vars are zeros
for (Index i = 0; i < numLocals; i++) {
+ auto type = func->getLocalType(i);
if (func->isParam(i)) {
#ifdef RSE_DEBUG
std::cout << "new param value for " << i << '\n';
#endif
start[i] = getUniqueValue();
+ } else if (type.isRef() && !type.isNullable()) {
+#ifdef RSE_DEBUG
+ std::cout << "new unique value for non-nullable " << i << '\n';
+#endif
+ start[i] = getUniqueValue();
} else {
- start[i] =
- getLiteralValue(Literal::makeZeros(func->getLocalType(i)));
+ start[i] = getLiteralValue(Literal::makeZeros(type));
}
}
} else {
diff --git a/test/lit/passes/rse-gc.wast b/test/lit/passes/rse-gc.wast
new file mode 100644
index 000000000..7bea92260
--- /dev/null
+++ b/test/lit/passes/rse-gc.wast
@@ -0,0 +1,15 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
+;; RUN: wasm-opt %s --rse --enable-gc-nn-locals -all -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (func $10
+ ;; CHECK-NEXT: (local $1 (ref func))
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $10
+ ;; A non-nullable local. The pass should ignore it (as we cannot optimize
+ ;; anything here anyhow: the code must assign to the local before reading from
+ ;; it, so no sets can be redundant in that sense).
+ (local $1 (ref func))
+ )
+)