<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal">
<ul>
<li>llvm-dev</li>
</ul>

<p dir="auto">On 25 Aug 2020, at 13:53, Florian Hahn wrote:</p>

</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">Hi,<br>
<br>
It appears that Clang generates calls to `llvm.memcpy` with potentially overlapping arguments in some cases.<br>
<br>
For the snippet below<br>
<br>
struct S<br>
{<br>
  char s[25];<br>
};<br>
<br>
struct S *p;<br>
<br>
void test2() {<br>
 ...<br>
  foo (&b, 1);<br>
  b = a;<br>
  b = *p;<br>
...<br>
}<br>
<br>
<br>
Clang uses `llvm.memcpy` to copy the struct:<br>
<br>
  call void @foo(%struct.S* %2, i32 1)<br>
  %7 = bitcast %struct.S* %2 to i8*<br>
  %8 = bitcast %struct.S* %1 to i8*<br>
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %7, i8* align 1 %8, i64 25, i1 false)<br>
  %9 = load %struct.S*, %struct.S** @p, align 8<br>
  %10 = bitcast %struct.S* %2 to i8*<br>
  %11 = bitcast %struct.S* %9 to i8*<br>
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %10, i8* align 1 %11, i64 25, i1 false)<br>
<br>
<br>
In the C example, `foo` could set `p = &b` and then `b = *p` would just copy the contents from `b` into `b`. This means that the the arguments to the second llvm.memcpy call may overlap, which seems not allowed according to the current version of the LangRef (<a href="https://llvm.org/docs/LangRef.html#llvm-memcpy-intrinsic" style="color:#777">https://llvm.org/docs/LangRef.html#llvm-memcpy-intrinsic</a>). This is problematic, because the fact is used in BasicAliasAnalysis for example (<a href="https://github.com/llvm/llvm-project/blob/master/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L982" style="color:#777">https://github.com/llvm/llvm-project/blob/master/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L982</a>).<br>
<br>
The full, build-able example can be found here: <a href="https://godbolt.org/z/PY1vKq" style="color:#777">https://godbolt.org/z/PY1vKq</a><br>
<br>
I might be missing something, but it appears that Clang should not create call to `llvm.memcpy` unless it can guarantee the arguments cannot overlap. I am not sure what the best alternative to `llvm.memcpy` would be in case the arguments overlap.</p>
</blockquote></div>
<div style="white-space:normal">

<p dir="auto">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?).</p>

<p dir="auto">I think we have are four options:</p>

<ol>
<li value="1">We can relax <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">llvm.memcpy</code> to allow exact overlap.  Practically, this would depend on memcpy being a no-op on exact overlap; we definitely wouldn’t want <em>LLVM</em> to have to start inserting control flow around memcpy calls.</li>
<li value="2">We can make Clang emit assignments with <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">llvm.memmove</code>.  This would make assignment work even with non-exact overlap, which is unnecessary; I’m not sure the cost is that high.</li>
<li value="3">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.</li>
<li value="4">We can add a new intrinsic — or some sort of decoration of the existing one — that does a memcpy but allows exact overlap.</li>
</ol>

<p dir="auto">John.</p>
</div>
</div>
</body>
</html>