Description
Consider this:
(module
(func $0
(nop)
)
(func $1
(nop)
)
(func "export" (result funcref)
(ref.func $1)
)
)
Running duplicate function elimination on this, it will merge $1
into $0
. It will turn (ref.func $1)
into (ref.func $0)
as a result. But then the fuzzer will see that before opts this returned a reference to the name "1" and afterwards to "0" which looks like a bug.
But is it..? Calling the function will show no difference in behavior. OTOH, comparing references on the outside would notice a difference if we return (ref.func $0)
from another funciton - before optimizations the two references are different, but not after.
If this is not a valid optimization, it seems like duplicate function elimination and other passes need to be very careful about any function whose reference is taken - similar to how they are careful about references to them in the table (but worse in some cases, as the table may be internal sometimes).