This is an archive of the discontinued LLVM Phabricator instance.

[AA] Model operand bundles more precisely
ClosedPublic

Authored by nikic on Aug 2 2022, 3:52 AM.

Details

Summary

Based on D130896, we can model operand bundles more precisely. In addition to the baseline ModRefBehavior, a reading/clobbering operand bundle may also read/write all locations. For example, a memcpy with deopt bundle can read any memory, but only write argument memory.

This means that getModRefInfo() for memcpy with a pointer that does not alias the arguments results in Ref, rather than ModRef, without the need to implement any special handling.

Depends on D130896.

Diff Detail

Event Timeline

nikic created this revision.Aug 2 2022, 3:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2022, 3:52 AM
nikic requested review of this revision.Aug 2 2022, 3:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2022, 3:52 AM
nikic updated this revision to Diff 450723.Aug 8 2022, 1:03 AM

Update OperandBundles/basic-aa-argmemonly.ll test, which now optimizes as well.

Replying only to this text from your description:
"For example, a memcpy with deopt bundle can read and write argument memory, but only read inaccessible and other memory."

I can't quite parse exactly what you mean here, but it *sounds* like you're saying the deopt bundle isn't allowed to read arbitrary (captured) memory. If so, we've talked ourselves into a bad result, because that's exactly what deopt needs to do.

Conceptually, "deopt" captures the abstract machine state of the running thread. The arguments to deopt are obviously part of that, but so is any memory which is a) visible from another thread, or b) visible from any of the captured state. So, in general, a deopt operand needs to read all memory which we can't *explicitly* prove hasn't been captured at or before the call.

nikic edited the summary of this revision. (Show Details)Sep 1 2022, 12:09 AM
nikic added a comment.Sep 1 2022, 12:12 AM

Replying only to this text from your description:
"For example, a memcpy with deopt bundle can read and write argument memory, but only read inaccessible and other memory."

I can't quite parse exactly what you mean here, but it *sounds* like you're saying the deopt bundle isn't allowed to read arbitrary (captured) memory. If so, we've talked ourselves into a bad result, because that's exactly what deopt needs to do.

Conceptually, "deopt" captures the abstract machine state of the running thread. The arguments to deopt are obviously part of that, but so is any memory which is a) visible from another thread, or b) visible from any of the captured state. So, in general, a deopt operand needs to read all memory which we can't *explicitly* prove hasn't been captured at or before the call.

The phrasing here was unnecessarily confusing. What we want to model is that memcpy+deopt can read any memory and write argument memory. Importantly, this excludes *writing* to captured memory.

ebrevnov added inline comments.Sep 1 2022, 2:30 AM
llvm/include/llvm/Analysis/AliasAnalysis.h
267 ↗(On Diff #450723)

Was wondering why you missing this when looking into D130896. Not super critical but would be nice if you move it there.

368 ↗(On Diff #450723)

Same suggestion as for writeOnly. Let's move it to the patch where API is introduced.

reames added a comment.Sep 1 2022, 8:01 AM

Replying only to this text from your description:
"For example, a memcpy with deopt bundle can read and write argument memory, but only read inaccessible and other memory."

I can't quite parse exactly what you mean here, but it *sounds* like you're saying the deopt bundle isn't allowed to read arbitrary (captured) memory. If so, we've talked ourselves into a bad result, because that's exactly what deopt needs to do.

Conceptually, "deopt" captures the abstract machine state of the running thread. The arguments to deopt are obviously part of that, but so is any memory which is a) visible from another thread, or b) visible from any of the captured state. So, in general, a deopt operand needs to read all memory which we can't *explicitly* prove hasn't been captured at or before the call.

The phrasing here was unnecessarily confusing. What we want to model is that memcpy+deopt can read any memory and write argument memory. Importantly, this excludes *writing* to captured memory.

Ah, glad to hear we're on the same page.

reames accepted this revision.Sep 21 2022, 3:38 PM

LGTM

llvm/lib/Analysis/AliasAnalysis.cpp
237–238

After staring at this for a bit, I concluded this was correct, but the bit about explicitly ignoring the InaccessibleMem effects here is subtle, and might be worth an explicit call out. The current comment/structure makes it look like the ignoring InaccessibleMem in lower points might be a mistake.

This revision is now accepted and ready to land.Sep 21 2022, 3:38 PM
This revision was landed with ongoing or failed builds.Sep 22 2022, 2:15 AM
This revision was automatically updated to reflect the committed changes.