-
Notifications
You must be signed in to change notification settings - Fork 745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix v8 -O0 take 2 #899
Fix v8 -O0 take 2 #899
Conversation
…remove it later, as it may be necessary due to wasm rules from the parent (e.g. the function fallthrough may need a block i32 even if the block ends in a return). at the end of asm2wasm, make sure to create the proper types for the function fallthrough, which is special (as asm2wasm doesn't emit other fallthroughs itself, not before optimization). rework how autodrop operates in order to work in this new scheme, by dropping things directly, not looking at higher scopes to see if used
…ing us to propagate a type necessary from the bottom up
… used, and it can make the block have a value, which is wrong
…their children must have the same type as them if they are concretely typed
Ah, I spoke too soon, I see some errors, still not done on the correctness side. |
…ns, the fallthrough must be typed that way (unreachable is not acceptable any more). this requires changing the binaryen C API to allow forcing the type of a block
This also required C API changes, to provide the type of a block. So this was a lot more work than expected, but it does seem to be ok now, nightly fuzzing + test suite appear to pass. The spec tests are still broken though. |
… it is just on control flow structures that it isn't
Added some more validation improvements. This now seems to pass the spec tests too. Note on s2wasm: it has tests that contain typed empty blocks (like |
…ve put an if at the end of a block, and if the block if is typed, then so now must be the if (it must have both arms of unreachable type, so this is ok to do)
In more "test suite is never enough" news, tests pass and fuzzing found nothing, but a failure occurred on Unreal. Fix pushed, details in there. |
…inter pass while debugging
Fuzzing found another bug. I guess this makes sense - this is a large change to the type system, so fallout is to be expected. It'll take a while to stabilize again. The last commit fixes it, but also worries me because it seems to indicate we must handle a lot more corner cases in each pass. We need to find a better approach, I think. |
Or maybe I still don't understand the new wasm type system rules. Can someone confirm if this should or should not validate?
|
Also whether this should or shouldn't:
|
And the same two questions with the if replaced by a select (I assume the answers are the same, but just to be sure). |
The first example does not validate, and the second does. The answers are the same for When replacing a |
Thanks. Ok, then this is a serious issue. That transform, of
into
was previously valid, because in the latter case our type system gives the block type The result is that in our current type system we cannot replace a node in the ast with another node with the same type ( One option is to change our type system to disallow A downside to doing that change is that it means we can't do the above transformation - it would be disallowed by type system logic as the first has type Instead, another alternative is to keep the type system as it is, i.e. allow |
Fwiw I've been exploring similar solutions, so settling the types for the encoding as part of the encoding stage. I also throw away a lot more of the type information in some IRs, and derive it at a later stage, to make it easier to work with the IR. For unreachable code, in some depth first walks of the code it returns the reachability of the child, which can be used in the parent to drop the dead code as appropriate. Block ends have a redundant |
An alternative I am considering, and would appreciate feedback on, is as follows:
|
Or replace the
All branches to the block label should have the same type, so if the end of the block is unreachable then use one of the other paths, and if there is an exit path then it seems odd to label the block as |
Superceded by #911. |
This is an alternative to #897, which turned out to not be enough. This PR has a more general fix, that seems to get everything to run in v8 and sm.
Principles:
if i32
, which would mean we need to fix up the children of that if, etc. Instead, asm.js input doesn't have fallthrough values anyhow, so just use that information up front.block i32
to end in a return, which has unreachable type, but if the block ends in another block, the child block must bei32
as well. Control flow structures are special in wasm, it seems.finalize
works.finalize
without a parameter will not remove a type likei32
. In other words, if you have ablock i32
, the finalizing it will not remove that type, even if it has nobrs
and ends in areturn
. This lets us preserve the proper types through optimizations. Once we set a concrete type, it stays unless we explicitly remove it.finalize(type)
(with a param) does allow changing the type to anything, it just sets the provided type directly, no matter what it is.finalize
with and without a param propagate the type into child control flow structure nodes. So whether a concrete type already existed or whether we just changed one, we make the children consistent with the parent.This PR is not ready to land, though, as these changes broke us on the spec tests. It might be best if someone that understands the type checking rules of the spec better than me looks at that part.