[llvm-commits] [llvm-gcc-4.2] r90914 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Dale Johannesen
dalej at apple.com
Tue Dec 8 17:24:15 PST 2009
On Dec 8, 2009, at 4:55 PMPST, Stuart Hastings wrote:
> Author: stuart
> Date: Tue Dec 8 18:55:56 2009
> New Revision: 90914
>
> URL: http://llvm.org/viewvc/llvm-project?rev=90914&view=rev
> Log:
> If a callee returns a structure in registers, but the stored image of
> those registers is bigger than the destination, store the registers
> into a temporary, and copy the desired (smaller) part to the
> destination. <rdar://problem/7437022>
> The original testcase returned an array of three 32-bit floats,
> wrapped in a struct; the value was returned as two doubles in xmm0/1,
> and stored as a 128-bit value.
You're assuming the useful bits in the temp are at the address of the
temp; this might not be true for some targets, especially big-endian
ones. I'm therefore inclined to think this should go in the target-
specific area(s). Don't know of a counterexample offhand, but please
test on PPC in case I'm wrong:) (gcc compatibility tests at least).
> Modified:
> llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
>
> Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=90914&r1=90913&r2=90914&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
> +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Dec 8 18:55:56 2009
> @@ -2776,8 +2776,26 @@
> return 0;
>
> if (Client.isAggrReturn()) {
> - Value *Dest = BitCastToType(DestLoc->Ptr, Call->getType()-
> >getPointerTo());
> - LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,Dest,DestLoc-
> >Volatile,Builder);
> + if (TD.getTypeAllocSize(Call->getType()) <=
> TD.getTypeAllocSize(DestLoc->Ptr->getType())) {
> + Value *Dest = BitCastToType(DestLoc->Ptr, Call->getType()-
> >getPointerTo());
> + LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,Dest,DestLoc-
> >Volatile,Builder);
> + } else {
> + // The call will return an aggregate value in registers, but
> + // those registers are bigger than DestLoc. Allocate a
> + // temporary to match the registers, store the registers there,
> + // cast the temporary into the correct (smaller) type, and
> using
> + // the correct type, copy the value into DestLoc. Assume the
> + // optimizer will delete the temporary and clean this up.
> + AllocaInst *biggerTmp = CreateTemporary(Call->getType());
> + LLVM_EXTRACT_MULTIPLE_RETURN_VALUE(Call,biggerTmp,/
> *Volatile=*/false,
> + Builder);
> + EmitAggregateCopy(*DestLoc,
> + MemRef(BitCastToType(biggerTmp,Call->getType()->
> + getPointerTo()),
> + DestLoc->getAlignment(),
> + DestLoc->Volatile),
> + TREE_TYPE(exp));
> + }
> return 0;
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list