diff options
author | Thomas Lively <tlively@google.com> | 2024-09-17 19:59:26 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-18 02:59:26 +0000 |
commit | b381a8c82030c2be3d1605d6f2854098f039f617 (patch) | |
tree | c751c4c23432fb35491896498163c1df8c67172e /test/lit/passes | |
parent | a99b48a4502628d46683fc85697251db3a8069b0 (diff) | |
download | binaryen-b381a8c82030c2be3d1605d6f2854098f039f617.tar.gz binaryen-b381a8c82030c2be3d1605d6f2854098f039f617.tar.bz2 binaryen-b381a8c82030c2be3d1605d6f2854098f039f617.zip |
Improve types for null accesses and remove hacks (#6954)
When a struct.get or array.get is optimized to have a null reference
operand, its return type loses meaning since the operation will always
trap. Previously when refinalizing such expressions, we just left their
return type unchanged since there was no longer an associated struct or
array type to calculate it from. However, this could lead to a strange
setup where the stale return type was the last remaining use of some
heap type in the module. That heap type would never be emitted in the
binary, but it was still used in the IR, so type optimizations would
have to keep updating it. Our type collecting logic went out of its way
to include the return types of struct.get and array.get expressions to
account for this strange possibility, even though it otherwise collected
only types that would appear in binaries.
In principle, all of this should have applied to `call_ref` as well, but
the type collection logic did not have the necessary special case, so
there was probably a latent bug there.
Get rid of these special cases in the type collection logic and make it
impossible for the IR to use a stale type that no longer appears in the
binary by updating such stale types during finalization. One possibility
would have been to make the return types of null accessors unreachable,
but this violates the usual invariant that unreachable instructions must
either have unreachable children or be branches or `(unreachable)`.
Instead, refine the return types to be uninhabitable non-nullable
references to bottom, which is nearly as good as refining them directly
to unreachable.
We can consider refining them to `unreachable` in the future, but
another problem with that is that it would currently allow the parsers
to admit more invalid modules with arbitrary junk after null accessor
instructions.
Diffstat (limited to 'test/lit/passes')
-rw-r--r-- | test/lit/passes/local-subtyping.wast | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/test/lit/passes/local-subtyping.wast b/test/lit/passes/local-subtyping.wast index d5fc3d63d..04890521d 100644 --- a/test/lit/passes/local-subtyping.wast +++ b/test/lit/passes/local-subtyping.wast @@ -274,7 +274,7 @@ ;; CHECK: (func $multiple-iterations-refinalize-call-ref-bottom (type $0) ;; CHECK-NEXT: (local $f nullfuncref) - ;; CHECK-NEXT: (local $x anyref) + ;; CHECK-NEXT: (local $x (ref none)) ;; CHECK-NEXT: (local.set $f ;; CHECK-NEXT: (ref.null nofunc) ;; CHECK-NEXT: ) |