This is an archive of the discontinued LLVM Phabricator instance.

[WPD] Don't optimize calls more than once
ClosedPublic

Authored by aeubanks on Jun 23 2021, 10:49 AM.

Details

Summary

WPD currently assumes that there is a one to one correspondence between
type test assume sequences and virtual calls. However, with
-fstrict-vtable-pointers this may not be true. This ends up causing
crashes when we try to optimize a virtual call more than once (
applyUniformRetValOpt()/applyUniqueRetValOpt()/applyVirtualConstProp()/applySingleImplDevirt()).

applySingleImplDevirt() actually didn't previous crash because it would
replace the devirtualized call with the same direct call. Adding an
assert that the call is indirect causes the corresponding test to crash
with the rest of the patch.

This makes Chrome successfully build with -fstrict-vtable-pointers + WPD.

Diff Detail

Event Timeline

aeubanks created this revision.Jun 23 2021, 10:49 AM
aeubanks requested review of this revision.Jun 23 2021, 10:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 23 2021, 10:49 AM

WPD currently assumes that each vtable load corresponds to one virtual call. However, with -fstrict-vtable-pointers this may not be true.

In the test case there is still a one to one correlation between the vtable load and virtual call. Do you mean that it can correspond to more than one type test assume sequence?

This probably requires more test coverage, but I'm not super familiar

WPD currently assumes that each vtable load corresponds to one virtual call. However, with -fstrict-vtable-pointers this may not be true.

In the test case there is still a one to one correlation between the vtable load and virtual call. Do you mean that it can correspond to more than one type test assume sequence?

Originally there are two vtable loads, each with a type test assume sequence. The vtable loads become coalesced, leaving two type test assume sequences for one vtable load.

This probably requires more test coverage, but I'm not super familiar

WPD currently assumes that each vtable load corresponds to one virtual call. However, with -fstrict-vtable-pointers this may not be true.

In the test case there is still a one to one correlation between the vtable load and virtual call. Do you mean that it can correspond to more than one type test assume sequence?

Originally there are two vtable loads, each with a type test assume sequence. The vtable loads become coalesced, leaving two type test assume sequences for one vtable load.

I assume -fstrict-vtable-pointers was what allowed the vtable loads to be coalesced? The description seems wrong though, since it is talking about one vtable load to one virtual call, and here that is still the case. I'm a little confused - in the test case why would there originally have been 2 vtable loads for that single virtual call?

It looks like the issue is that we no longer have a one to one correspondence between type test assume sequences and virtual calls - is that correct?

Also, do we need to do something similar for singleImplDevirt, or why does this issue not occur there?

aeubanks updated this revision to Diff 354142.Jun 23 2021, 7:55 PM

also handle singleImplDevirt

This probably requires more test coverage, but I'm not super familiar

WPD currently assumes that each vtable load corresponds to one virtual call. However, with -fstrict-vtable-pointers this may not be true.

In the test case there is still a one to one correlation between the vtable load and virtual call. Do you mean that it can correspond to more than one type test assume sequence?

Originally there are two vtable loads, each with a type test assume sequence. The vtable loads become coalesced, leaving two type test assume sequences for one vtable load.

I assume -fstrict-vtable-pointers was what allowed the vtable loads to be coalesced? The description seems wrong though, since it is talking about one vtable load to one virtual call, and here that is still the case. I'm a little confused - in the test case why would there originally have been 2 vtable loads for that single virtual call?

Oh my test case is confusing. I omitted the second virtual call in the test case and the crash still reproduced.

It looks like the issue is that we no longer have a one to one correspondence between type test assume sequences and virtual calls - is that correct?

Yeah I think your statement makes more sense.

Also, do we need to do something similar for singleImplDevirt, or why does this issue not occur there?

Ah I missed that. Probably it just happened that it didn't trigger in Chrome. Added to that part.

I'll try to come up with tests for all of the cases.

aeubanks edited the summary of this revision. (Show Details)Jun 23 2021, 7:56 PM
aeubanks updated this revision to Diff 354281.Jun 24 2021, 9:37 AM

add tests

aeubanks edited the summary of this revision. (Show Details)Jun 24 2021, 9:37 AM
aeubanks updated this revision to Diff 354286.Jun 24 2021, 10:00 AM

add back accidentally removed assert in applySingleImplDevirt()

This revision is now accepted and ready to land.Jun 24 2021, 12:15 PM
This revision was automatically updated to reflect the committed changes.