[llvm-commits] llvm-gcc aggregate copy

Eli Friedman eli.friedman at gmail.com
Wed May 28 03:22:41 PDT 2008


On Tue, May 27, 2008 at 11:46 PM, Duncan Sands <baldrick at free.fr> wrote:
> Hi Chris, I discussed this problem with Dale some time ago.
> Since gcc mainline produces exactly the same memcpy call, we
> decided not to worry about it.  I do remember a gcc guy telling
> me once that aggregate assignment assumes no overlap, so maybe
> there is nothing to worry about...

Hmm, just found it: C99 6.5.16.1p4, about the simple assignment
operator: "If the value being stored in an object is read from another
object that overlaps in any way the storage of the first object, then
the overlap shall be exact and the two objects shall have qualified or
unqualified versions of a compatible type; otherwise, the behavior is
undefined."  (C++ 5.17p8 is almost exactly the same.)  So at least for
C/C++, we are allowed by the standard to use a memcpy-like
implementation for struct assignment (but not actually memcpy, unless
we can make some sort of non-standard guarantee about the
implementation).

> My personal feeling is that
> memmove should be used and llvm should change it to memcpy if
> it can deduce that it is safe.  There is also the problem of
> small structs for which llvm-gcc produces a hand-made memcpy,
> i.e. a series of loads and stores.  That would need to be turned
> into something that works for overlapping objects.  One possibility
> (inefficient but works) is to compare the addresses of the two
> objects and copy in order of increasing address or decreasing address
> correspondingly.  A better solution is perhaps to exploit the new
> aggregates-as-first-class-values work and treat small structs as
> registers.

No matter what we do, memmove is fundamentally more expensive than
memcpy because it requires either an branch, some extra conditional
arithmetic, or a bunch of free space in registers.

We could add another intrinsic, llvm.struct.copy, which is memcpy that
allows equal pointers.  It would lower to an inline copy for small
copies, and a branch over a call to memcpy for larger ones.  That's
kind of messy, though.

-Eli



More information about the llvm-commits mailing list