[llvm-commits] llvm-gcc aggregate copy

Duncan Sands baldrick at free.fr
Tue May 27 23:46:14 PDT 2008


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...  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.

Ciao,

Duncan.

> After looking into PR2371, I tried out this C testcase with llvm-gcc  
> to see what it is generating:
> 
> struct foo { double x[100]; };
> void T(struct foo *F, struct foo* G) {
>    *F = *G;
> }
> 
> llvm-gcc currently compiles this into:
> 
> define void @T(%struct.foo* %F, %struct.foo* %G) nounwind  {
> entry:
> 	%tmp2 = bitcast %struct.foo* %F to i8*		; <i8*> [#uses=1]
> 	%tmp13 = bitcast %struct.foo* %G to i8*		; <i8*> [#uses=1]
> 	tail call void @llvm.memcpy.i32( i8* %tmp2, i8* %tmp13, i32 800, i32  
> 4 )
> 	ret void
> }
> 
> The problem is that F/G can be the same pointer, so using memcpy is  
> undefined.  Should llvm-gcc start emitting llvm.memmove calls, or is  
> there something with GCC trees that can be improved to know when  
> memmove is needed?



More information about the llvm-commits mailing list