This is an archive of the discontinued LLVM Phabricator instance.

Do not merge memcpy if the first source is a parameter of coroutine function
AbandonedPublic

Authored by lxfind on Apr 28 2021, 6:48 PM.

Details

Reviewers
nikic
asbirlea
Summary

This is a temporary walkaround of https://bugs.llvm.org/show_bug.cgi?id=48857.
MemCpyOpt is able to merge two memcpy intrinsics, if the destination of the first memcpy is the same as the source of the second, and there are no changes to the values.
If the first memcpy's source is a parameter of a coroutine function, unfortunately this optimization will not work.
Parameters of a coroutine function, despiite marked as readonly (for rvalues), may be destroyed when the coroutine is suspended.
If the second memcpy happens after coroutine suspension, the parameter may have died already and we cannot copy from it at that point.
Hence if the source of the first memcpy is a parameter, we don't merge memcpys.

Diff Detail

Event Timeline

lxfind created this revision.Apr 28 2021, 6:48 PM
lxfind requested review of this revision.Apr 28 2021, 6:48 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 28 2021, 6:48 PM

Since this is broken anyways, and we are far from branching point, perhaps we should wait until there is a proper fix?

Since this is broken anyways, and we are far from branching point, perhaps we should wait until there is a proper fix?

Personally I think that's better. But it seems some are relying on master. I can comment on the bug. This patch at least provides a way for people to walk around it locally if they need to. We don't have to land it.

rnk added a subscriber: rnk.Apr 29 2021, 11:54 AM

I don't think this is a reasonable fix. We can't just go around dropping special cases for coroutines in every transform. There are other ways to sink loads from byval memory across a suspend point. I know you are offering this as a quick fix and intend to do a proper fix later, but I don't think it's the right tradeoff of expedience to tech debt for the overall LLVM project.

There must be some logic in memoryssa or our alias analysis code that believes that byval arguments are immutable. Is it not just a matter of moving the special case to the analysis? Have the analysis check if the argument's parent function is a coroutine?

rnk added a comment.May 4 2021, 12:27 PM

Since we are already in the space of finding workarounds, when is the memcpy of the byval parameter introduced? Is it compiler generated? If so, could it be marked volatile there? This would limit the coroutines-specific workaround to coroutine code, which move the tech debt burden from generic LLVM code to coroutines code. That would work.

Since we are already in the space of finding workarounds, when is the memcpy of the byval parameter introduced? Is it compiler generated? If so, could it be marked volatile there? This would limit the coroutines-specific workaround to coroutine code, which move the tech debt burden from generic LLVM code to coroutines code. That would work.

Thanks for the suggestions. We may have a way to fix this within coroutine passes (by explicitly looking for byval params and copy them).
@ChuanqiXu is looking into it.

I am trying to fix this within coroutine passes in D101980.

nikic requested changes to this revision.Jun 9 2021, 1:47 PM

It looks like a different fix is being pursued, so marking this as changes requested to move it off the review queue.

This revision now requires changes to proceed.Jun 9 2021, 1:47 PM
lxfind abandoned this revision.Jun 9 2021, 7:41 PM
lxfind added a comment.Jun 9 2021, 7:49 PM

I found a more proper fix in D104007.