This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Fully invalidate SCEVUnknown on RAUW
ClosedPublic

Authored by nikic on Feb 17 2022, 3:10 AM.

Details

Summary

When a SCEVUnknown gets RAUWd, we currently drop it from the folding set, but don't forget memoized values. I believe we should be treating RAUW the same way as deletion here and invalidate all caches and dependent expressions.

I don't have any specific cases where this causes issues right now. This patch is inspired by the FIXME in https://reviews.llvm.org/D119488.

Diff Detail

Event Timeline

nikic created this revision.Feb 17 2022, 3:10 AM
nikic requested review of this revision.Feb 17 2022, 3:10 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 17 2022, 3:10 AM
nikic edited the summary of this revision. (Show Details)Feb 17 2022, 3:12 AM

I don't think is quite right. We can have SCEV forget all of it's memoized results, but we can't disallow a client hanging onto an expression containing a SCEVUnknown over a RAUW. Given that, I think we need to explicitly forget, but keep the bit about changing the value pointer to the new value.

I don't think is quite right. We can have SCEV forget all of it's memoized results, but we can't disallow a client hanging onto an expression containing a SCEVUnknown over a RAUW. Given that, I think we need to explicitly forget, but keep the bit about changing the value pointer to the new value.

This is making the behavior the same as for erasing the value, so clients already need to deal with SCEVUnknown holding onto a nullptr (if they both cache it and inspect it that deeply).

Though I don't mind keeping the setValPtr(New), that seems harmless.

nikic updated this revision to Diff 410473.Feb 22 2022, 1:15 AM

Don't replace value pointer with nullptr.

mkazantsev added a comment.EditedFeb 24 2022, 8:51 PM

When something is already erased from uniqueSCEVs, but is still in use, I'm pretty sure verify() should break somewhere on this situation. Is this something that is happening in reality?

I think we've been too permissive to holding various kinds of dangling pointers, and this caused us *very* nasty bugs. If we can avoid this situation, I think we must.

nikic added a comment.Feb 25 2022, 3:58 AM

When something is already erased from uniqueSCEVs, but is still in use, I'm pretty sure verify() should break somewhere on this situation. Is this something that is happening in reality?

I just checked that this patch does fix eliminate-max.ll with D119488, so clearly this does happen, and we do need to invalidate here. I think the reason why this is not more problematic in practice is that SCEVCallbackVH will perform a use-def walk on RAUW and remove values from the value map, so we end up mostly doing the invalidation through that mechanism. But of course, this is not quite the same, as the SCEV may be part of structures other than the value map etc.

mkazantsev resigned from this revision.Mar 4 2022, 12:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 4 2022, 12:13 AM
reames accepted this revision.Mar 5 2022, 12:48 PM

LGTM

This revision is now accepted and ready to land.Mar 5 2022, 12:48 PM
This revision was landed with ongoing or failed builds.Mar 7 2022, 12:40 AM
This revision was automatically updated to reflect the committed changes.