diff options
author | Alon Zakai <azakai@google.com> | 2021-06-18 11:32:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-18 11:32:44 -0700 |
commit | e1586984480daf475d0941d6b6b5640fbec80558 (patch) | |
tree | 83683e095f51acf35ec2f2a438d04fc20adb46dc | |
parent | ea0b9ee1e1083962da9bfa52fa09870fcc4f72bb (diff) | |
download | binaryen-e1586984480daf475d0941d6b6b5640fbec80558.tar.gz binaryen-e1586984480daf475d0941d6b6b5640fbec80558.tar.bz2 binaryen-e1586984480daf475d0941d6b6b5640fbec80558.zip |
[Wasm GC] Fix RSE on non-nullable locals (#3943)
RedundantSetElimination checks if a local already has the default
value when we assign the default to it. For a non-nullable local, however,
there is no initial value - it cannot be used before it is assigned to. So
we just need to skip such locals, and not assume they contain a default
value we can compare against (we would assert on trying to create a
"zero" for such a non-nullable type).
Fixes #3942
-rw-r--r-- | src/passes/RedundantSetElimination.cpp | 9 | ||||
-rw-r--r-- | test/lit/passes/rse-gc.wast | 15 |
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)) + ) +) |