Skip to content
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

Ensure symmetric results in PossibleConstantValues #4662

Merged
merged 8 commits into from
May 13, 2022
Merged

Ensure symmetric results in PossibleConstantValues #4662

merged 8 commits into from
May 13, 2022

Conversation

kripken
Copy link
Member

@kripken kripken commented May 12, 2022

Previously we could return different results depending on the order we
noted things:

note(anyref.null);
note(funcref.null);
get() => anyref.null

note(funcref.null);
note(anyref.null);
get() => funcref.null

This is correct, as nulls are equal anyhow, and any could be used in
the location we are optimizing. However, it can lead to nondeterminism
if the caller's order of notes is nondeterministic. That is the case in
DeadArgumentElimination, where we scan functions in parallel, then
merge them without special ordering.

To fix this, make the note operation symmetric. That seems simplest and
least likely to be confusing. We can use the LUB to do that.

To avoid duplicating the null logic, refactor note() to use combine().

@kripken kripken requested review from tlively and aheejin May 12, 2022 19:10
Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, although I guess we will have to update this code somehow if we remove func <: any and end up with multiple unrelated nulls.

@aheejin
Copy link
Member

aheejin commented May 12, 2022

LGTM, although I guess we will have to update this code somehow if we remove func <: any and end up with multiple unrelated nulls.

Is func not a subtype anymore? And I noticed externref was deleted from Binaryen recently. Have we decided to use anyref for that purpose and get rid of externref eventually?

Comment on lines +114 to +116
auto type = getConstantLiteral().type.getHeapType();
auto otherType = other.getConstantLiteral().type.getHeapType();
auto lub = HeapType::getLeastUpperBound(type, otherType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we directly use Type::getLeastUpperBound?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, but I think the clearer thing is to LUB on the heap type, because nullability is not relevant here... but maybe the real issue here is that makeNull gets a type and not a heap type - if it got a heap type then we wouldn't have two options here, which seems better. Let me look into that as a refactor PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of the types are null at this point. Doesn't that mean both types are nullable anyway here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly, the types must be nullable anyhow. So we really just need the least upper bound of the heap type, which is the only thing that can be different between them.

After #4664 the code here will be something like this, which I think is good:

auto lub = HeapType::getLeastUpperBound(type, otherType)
if (lub != type) {
  value = Literal::makeNull(lub);
  return true;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated after that PR landed.

@tlively
Copy link
Member

tlively commented May 12, 2022

Is func not a subtype anymore?

func is still a subtype of any for now, although we're discussing changing this: WebAssembly/gc#293

And I noticed externref was deleted from Binaryen recently. Have we decided to use anyref for that purpose and get rid of externref eventually?

Yep, we decided to make extern and any the same type, so we didn't need both of them in Binaryen anymore.

@kripken kripken marked this pull request as ready for review May 13, 2022 17:17
@kripken kripken merged commit 4edfcc9 into main May 13, 2022
@kripken kripken deleted the daenull branch May 13, 2022 23:39
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.

3 participants