[cfe-dev] [llvm-dev] Clang generates calls to llvm.memcpy with overlapping arguments, but LangRef requires the arguments to not overlap
Florian Hahn via cfe-dev
cfe-dev at lists.llvm.org
Mon Sep 14 12:02:20 PDT 2020
> On Aug 28, 2020, at 21:49, Florian Hahn <florian_hahn at apple.com> wrote:
>
>
>
>> On Aug 26, 2020, at 16:40, Florian Hahn via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
>>> On Aug 25, 2020, at 23:06, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
>>> C allows overlapping assignments only when the overlap is exact, i.e. the addresses are exactly the same. I agree that just emitting memcpy isn’t strictly legal, because neither C nor LLVM allows even exact overlap. On the other hand, Clang would really like to avoid emitting extra control flow here, because exact overlap is uncommon enough that emitting a no-op memcpy (if it were indeed a no-op) is definitely the right trade-off in practice; and LLVM probably won’t reliably remove branches around a memcpy call if we add them. And it’s very hard to imagine a memcpy implementation that actually wouldn’t work with exact overlap (maybe something that tried to just remap pages?).
>>>
>>> I think we have are four options:
>>>
>>> We can relax llvm.memcpy to allow exact overlap. Practically, this would depend on memcpy being a no-op on exact overlap; we definitely wouldn’t want LLVM to have to start inserting control flow around memcpy calls.
>>> We can make Clang emit assignments with llvm.memmove. This would make assignment work even with non-exact overlap, which is unnecessary; I’m not sure the cost is that high.
>>> We can make Clang emit an explicit check and control flow around memcpy when there might be overlap. Clang IRGen should already maintain the right information to avoid doing this when e.g. initializing a variable.
>>> We can add a new intrinsic — or some sort of decoration of the existing one — that does a memcpy but allows exact overlap.
>>
>> Thanks for summarizing the options! I think 4. would probably the safest option, because we won’t have to track down the places that use the non-overlapping assumption. There might also be such cases somewhere downstream, which might be broken silently. If Clang already has the information when the operands cannot overlap (as mentioned in 3.), we only have to emit the non-overlapping version for those cases, causing the least amount of change for the generated IR.
>>
>> 1. Also seems possible (there probably are not too many places in LLVM that use the non-overlapping assumption), but I think in some cases the non-overlapping info can be a useful property to convey for frontends.
>
>
> I took a look at the places in LLVM that make use of the non-overlapping guarantee and it appears BasicAliasAnalysis is the only place. I put up a patch https://reviews.llvm.org/D86815 <https://reviews.llvm.org/D86815> to illustrate the impact on the code & tests. It seems quite manageable. It might be feasible to start with removing the guarantee and re-introduce a variant with the additional guarantee.
>
> What do you think? Alternatively I can also put up a patch to add a new variant without the guarantee. In that case, I would appreciate some pointers on how to tell whether arguments are guaranteed to not overlap in Clang.
Just a quick update. The behavior of llvm.memcpy has been adjusted and the alias analysis code has been updated: https://reviews.llvm.org/rG1ddb3a369f7ebdf738486cd60261c3143658c0e6 <https://reviews.llvm.org/rG1ddb3a369f7ebdf738486cd60261c3143658c0e6>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200914/32d70734/attachment.html>
More information about the cfe-dev
mailing list