diff options
author | Alon Zakai <azakai@google.com> | 2023-05-05 09:55:23 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-05 16:55:23 +0000 |
commit | 515690c397c772f6eb0f9747c51fab69046c606b (patch) | |
tree | 53e227fa65a4dbd3d0c3ac6a638216643ec5a394 /src/wasm/wasm.cpp | |
parent | 426070cace6a3a2e5e95656623c325a53a4b924b (diff) | |
download | binaryen-515690c397c772f6eb0f9747c51fab69046c606b.tar.gz binaryen-515690c397c772f6eb0f9747c51fab69046c606b.tar.bz2 binaryen-515690c397c772f6eb0f9747c51fab69046c606b.zip |
[Wasm GC] Automatically make RefCast heap types more precise (#5704)
We already did this for nullablilty, and so for the same reasons we should do it
for heap types as well. Also, I realized that doing so would solve #5703, which
is the new test added for TypeRefining here.
The fuzz bug solved here is that our analysis of struct gets/sets will skip
copy operations - a read from a field that is written into it. And we skip
fallthrough values while doing so, since it doesn't matter if the read goes
through an if arm or a cast. An if would automatically get a more precise
type during refinalize, so this PR does the same for a cast basically.
Fixes #5703
Diffstat (limited to 'src/wasm/wasm.cpp')
-rw-r--r-- | src/wasm/wasm.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index c3f262998..552ec7e57 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -947,10 +947,24 @@ void RefCast::finalize() { type = Type::unreachable; return; } - // Do not unnecessarily lose non-nullability information. + + // Do not unnecessarily lose non-nullability info. We could leave this for + // optimizations, but doing it here as part of finalization/refinalization + // ensures that type information flows through in an optimal manner and can be + // used as soon as possible. if (ref->type.isNonNullable() && type.isNullable()) { type = Type(type.getHeapType(), NonNullable); } + + // Do not unnecessarily lose heap type info, as above for nullability. Note + // that we must check if the ref has a heap type, as we reach this before + // validation, which will error if the ref does not in fact have a heap type. + // (This is a downside of propagating type information here, as opposed to + // leaving it for an optimization pass.) + if (ref->type.isRef() && + HeapType::isSubType(ref->type.getHeapType(), type.getHeapType())) { + type = Type(ref->type.getHeapType(), type.getNullability()); + } } void BrOn::finalize() { |