<div dir="ltr">Benchmarks so far aren't looking good.<div><br></div><div>It's frustrating because as you say w/o profile information calling the library functions is a pretty good bet. Unfortunately, because we aggressive canonicalize loops into memcpy (and memset) we have a problem when the loop was actually the optimal emitted code.</div><div><br></div><div>I'm going to play with some options and see if there is a code sequence which is small enough to inline and has better performance tradeoffs than either the libcall or rep+movs pattern.</div><div><br></div><div><br></div><div>FWIW, some basic facts that my benchmark has already uncovered:</div><div>- Even as late as sandybridge, the performance of rep+movsb (emphasis on *b* there) is pretty terrible. rep+movsq is more plausible</div><div>- Haswell sees rep+mosvb slightly faster than rep+movsq, but not by much</div><div>- All of these are slower than a libcall on both sandybridge and haswell I've tried so far on everything but long (over 4k) sequences.</div><div>- rep+movsq tends to be the fastest over 4k on both sandybridge and haswell</div><div>- the only thing I've tried so far that makes my particular collection of benchmarks that are particularly impacted by this faster is an 8-byte loop... i didn't expect this to be faster than rep+movsq, but there you go....</div><div>  - it's worth noting that for at least some benchmarks, this is significant. the one I'm working on has perf hit between 5% and 50% depending on dataset for an 8-byte loop vs. memset libcall.</div><div><br></div><div>Still lots more measurements to do before any definite conclusions. I remain somewhat concerned about injecting PLT-based libcalls into so many places. LLVM is generating a *lot* of these.</div></div><br><div class="gmail_quote"><div dir="ltr">On Sat, Jul 22, 2017 at 12:04 AM David Li via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">davidxl added a comment.<br>
<br>
Do you have more benchmark numbers? For reference, here is GCC does (for sandybridge and above) for mempcy when size profile data is available:<br>
<br>
1. when the size is <= 24, use 8 byte copy loop or straightline code.<br>
2. when size is is between 24 and 128, use rep movsq<br>
3. when size is b above that, use libcall<br>
<br>
It is an interesting idea to consider PLT overhead here, but is there a better way to model the cost?<br>
<br>
I worry that without profile data, blindly using rep movsb may be problematic. Teresa has a pending patch to make use value profile information.  Without profile, if size matters, perhaps we can guard the expansion sequence with size checks.<br>
<br>
Also if the root cause<br>
<br>
<br>
<a href="https://reviews.llvm.org/D35750" rel="noreferrer" target="_blank">https://reviews.llvm.org/D35750</a><br>
<br>
<br>
<br>
</blockquote></div>