diff options
author | Alon Zakai <azakai@google.com> | 2024-11-05 15:49:50 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-05 15:49:50 -0800 |
commit | 92917c28ea6ef017e71a8a97eb364ed20bc52fe2 (patch) | |
tree | 549bddb482ed85933edf6f6b28978203f64c722d /src/wasm-interpreter.h | |
parent | 320867a7c61432691faa62892d5fd89e4f6bae6a (diff) | |
download | binaryen-92917c28ea6ef017e71a8a97eb364ed20bc52fe2.tar.gz binaryen-92917c28ea6ef017e71a8a97eb364ed20bc52fe2.tar.bz2 binaryen-92917c28ea6ef017e71a8a97eb364ed20bc52fe2.zip |
[GC] Fix ConstantFieldPropagation on incompatible types (#7054)
CFP is less precise than GUFA, in particular, when it flows around types then
it does not consider what field it is flowing them to, and its core data
structure is "if a struct.get is done on this type's field, what can be read?".
To see the issue this PR fixes, assume we have
A
/ \
B C
Then if we see struct.set $C, we know that can be read by a struct.get $A
(we can store a reference to a C in such a local/param/etc.), so we propagate
the value of that set to A. And, in general, anything in A can appear in B
(say, if we see a copy, a struct.set of struct.get that operates on types A,
then one of the sides might be a B), so we propagate from A to B. But
now we have propagated something from C to B, which might be of an
incompatible type.
This cannot cause runtime issues, as it just means we are propagating more
than we should, and will end up with less-useful results. But it can break
validation if no other value is possible but one with an incompatible type,
as we'd replace a struct.get $B with a value that only makes sense for C.
(The qualifier "no other value is possible" was added in the previous
sentence because if another one is possible then we'd end up with too
many values to infer anything, and not optimize at all, avoiding any error.)
Diffstat (limited to 'src/wasm-interpreter.h')
0 files changed, 0 insertions, 0 deletions