This is an archive of the discontinued LLVM Phabricator instance.

[CodeGen] Fix isGCValue utility for statepoint lowering
AbandonedPublic

Authored by skatkov on Mar 29 2020, 11:08 PM.

Details

Reviewers
reames
dantrushin
Summary

isGCValue should detect whether the deopt value is a GC pointer.
Currently it checks by finding the value in SI.Bases and SI.Ptrs.
However these dsata structures contains only those values which
has corresponding gc.relocate call. So we can miss GC value is it
does not have gc.relocate call (dead after the call).

At the same time specification requires for all deopt values which
can be modified by GC to be listed in gc values.
So we can check whether deopt value is listed in gc values.

Diff Detail

Event Timeline

skatkov created this revision.Mar 29 2020, 11:08 PM
dantrushin added inline comments.Mar 30 2020, 9:27 AM
llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
486

Well, this makes me to ask a question, see below (at lines 497 and 530)...

497

Is it correct that we process SI.Bases and SI.Ptrs here, not SI.GCArgs?

530

And here we lower not all GCArgs, but relocated pointers only....

reames requested changes to this revision.Mar 30 2020, 10:23 AM

Er, I think the specification simplify needs changed here. As we've discussed offline, it's impossible to enforce having a gc pointer in the deopt list always be in the gc list (in any form). This was a flaw in the specification from the begging and we should fix the docs, not try to hack up the code to preserve it a bit longer.

The key example of why this can't work:
%p1 = bitcast i8* %p to i8*
statepoint [gc = (%p1)], [deopt = (%p1)]

The optimizer is allowed to replace either use (or both) of %p1 with %p. If it updates only one of the two (entirely legal), the two sets do not overlap.

If we need to enforce a property for GC values within deopt list, we should directly use the type of the pointer in question. Anything else appears unsound.

This revision now requires changes to proceed.Mar 30 2020, 10:23 AM
skatkov marked 2 inline comments as done.Mar 30 2020, 9:17 PM

Er, I think the specification simplify needs changed here. As we've discussed offline, it's impossible to enforce having a gc pointer in the deopt list always be in the gc list (in any form). This was a flaw in the specification from the begging and we should fix the docs, not try to hack up the code to preserve it a bit longer.

The key example of why this can't work:
%p1 = bitcast i8* %p to i8*
statepoint [gc = (%p1)], [deopt = (%p1)]

The optimizer is allowed to replace either use (or both) of %p1 with %p. If it updates only one of the two (entirely legal), the two sets do not overlap.

If we need to enforce a property for GC values within deopt list, we should directly use the type of the pointer in question. Anything else appears unsound.

ok, then I will prepare a patch which eliminates the questionable requirement from spec.

In terms of fixing this one I see two ways to resolve it:

  1. Use the same isHandledGCPointerType utility as RewriteStatepointsForGC for detection of GC pointer
  2. Conservatively suggest any pointer to be a GC pointer.

What way do you prefer?

llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
497

It is fine due to it is only optimization and is not required for correctness.

530

That is also fine. Bases and Ptrs are build from GCArgs by elimination of the same values, so it is ok to lower only unique values.