Skip to content

[EH][GC] Fix nested pop after removing ref.cast #4407

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

Merged
merged 1 commit into from
Dec 29, 2021

Conversation

aheejin
Copy link
Member

@aheejin aheejin commented Dec 23, 2021

ref.cast can be statically removed when the ref's type is a subtype of
the intended RTT type and either of --ignore-implicit-traps or
--traps-never-happen is given:

if (passOptions.ignoreImplicitTraps || passOptions.trapsNeverHappen ||
!curr->rtt) {
// Aside from the issue of type incompatibility as mentioned above, the
// cast can trap if the types *are* compatible but it happens to be the
// case at runtime that the value is not of the desired subtype. If we
// do not consider such traps possible, we can ignore that. (Note,
// though, that we cannot do this if we cannot replace the current type
// with the reference's type.) We can also do this if this is a static
// cast: in that case, all we need to know about are the types.
if (HeapType::isSubType(curr->ref->type.getHeapType(), intendedType)) {
if (curr->rtt) {
replaceCurrent(getResultOfFirst(curr->ref,
builder.makeDrop(curr->rtt),
getFunction(),
getModule(),
passOptions));
} else {
replaceCurrent(curr->ref);
}
return;
}
}

Some more context: #4097 (comment)

But this can create a block in which a pop is nested, which makes the
catch invalid. The test in this PR is the same as the example given by
@kripken in #4237. This calls the fixup function
EHUtils::handleBlockNestedPops at the end of the pass to fix this.

Also, because this pass creates a lot of blocks in other patterns, I
think it is possible there can be other patterns to cause this kind of
pop nesting.

`ref.cast` can be statically removed when the ref's type is a subtype of
the intended RTT type and either of `--ignore-implicit-traps` or
`--traps-never-happen` is given: https://github.com/WebAssembly/binaryen/blob/083ab9842ec3d4ca278c95e1a33112ae7cd4d9e5/src/passes/OptimizeInstructions.cpp#L1603-L1624

Some more context: WebAssembly#4097 (comment)

But this can create a block in which a `pop` is nested, which makes the
`catch` invalid. The test in this PR is the same as the example given by
@kripken in WebAssembly#4237. This calls the fixup function
`EHUtils::handleBlockNestedPops` at the end of the pass to fix this.

Also, because this pass creates a lot of blocks in other patterns, I
think it is possible there can be other patterns to cause this kind of
`pop` nesting.
@aheejin aheejin requested review from kripken and tlively December 23, 2021 19:42
@aheejin aheejin merged commit ad723a1 into WebAssembly:main Dec 29, 2021
@aheejin aheejin deleted the ref_cast_pop_fix branch December 29, 2021 01:05
aheejin added a commit to aheejin/binaryen that referenced this pull request Dec 29, 2021
`ref.cast` can be statically removed when the ref's type is a subtype of
the intended RTT type and either of `--ignore-implicit-traps` or
`--traps-never-happen` is given: https://github.com/WebAssembly/binaryen/blob/083ab9842ec3d4ca278c95e1a33112ae7cd4d9e5/src/passes/OptimizeInstructions.cpp#L1603-L1624

Some more context: WebAssembly#4097 (comment)

But this can create a block in which a `pop` is nested, which makes the
`catch` invalid. The test in this PR is the same as the example given by
@kripken in WebAssembly#4237. This calls the fixup function
`EHUtils::handleBlockNestedPops` at the end of the pass to fix this.

Also, because this pass creates a lot of blocks in other patterns, I
think it is possible there can be other patterns to cause this kind of
`pop` nesting.
aheejin added a commit to aheejin/binaryen that referenced this pull request Dec 29, 2021
`ref.cast` can be statically removed when the ref's type is a subtype of
the intended RTT type and either of `--ignore-implicit-traps` or
`--traps-never-happen` is given: https://github.com/WebAssembly/binaryen/blob/083ab9842ec3d4ca278c95e1a33112ae7cd4d9e5/src/passes/OptimizeInstructions.cpp#L1603-L1624

Some more context: WebAssembly#4097 (comment)

But this can create a block in which a `pop` is nested, which makes the
`catch` invalid. The test in this PR is the same as the example given by
@kripken in WebAssembly#4237. This calls the fixup function
`EHUtils::handleBlockNestedPops` at the end of the pass to fix this.

Also, because this pass creates a lot of blocks in other patterns, I
think it is possible there can be other patterns to cause this kind of
`pop` nesting.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants