[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