[llvm] r183584 - Fix an assertion in MemCpyOpt pass.

Duncan Sands duncan.sands at gmail.com
Fri Jun 7 20:43:44 PDT 2013


Hi Shuxin,

On 08/06/13 02:51, Shuxin Yang wrote:
> On 6/7/13 4:39 PM, Eli Friedman wrote:
>> On Fri, Jun 7, 2013 at 3:45 PM, Shuxin Yang <shuxin.llvm at gmail.com
>> <mailto:shuxin.llvm at gmail.com>> wrote:
>>
>>     Author: shuxin_yang
>>     Date: Fri Jun  7 17:45:21 2013
>>     New Revision: 183584
>>
>>     URL: http://llvm.org/viewvc/llvm-project?rev=183584&view=rev
>>     Log:
>>       Fix an assertion in MemCpyOpt pass.
>>
>>       The MemCpyOpt pass is capable of optimizing:
>>           callee(&S); copy N bytes from S to D.
>>         into:
>>           callee(&D);
>>     subject to some legality constraints.
>>
>>       Assertion is triggered when the compiler tries to evalute
>>     "sizeof(typeof(D))",
>>     while D is an opaque-typed, 'sret' formal argument of function being compiled.
>>     i.e. the signature of the func being compiled is something like this:
>>       T caller(...,%opaque* noalias nocapture sret %D, ...)
>>
>>       The fix is that when come across such situation, instead of calling some
>>     utility functions to get the size of D's type (which will crash), we simply
>>     assume D has at least N bytes as implified by the copy-instruction.
>>
>>     rdar://14073661
>>
>>     Modified:
>>         llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
>>         llvm/trunk/test/Transforms/MemCpyOpt/memcpy.ll
>>
>>     Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
>>     URL:
>>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=183584&r1=183583&r2=183584&view=diff
>>     ==============================================================================
>>     --- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original)
>>     +++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Fri Jun  7
>>     17:45:21 2013
>>     @@ -626,8 +626,10 @@ bool MemCpyOpt::performCallSlotOptzn(Ins
>>            return false;
>>
>>          Type *StructTy = cast<PointerType>(A->getType())->getElementType();
>>     -    uint64_t destSize = TD->getTypeAllocSize(StructTy);
>>     -
>>     +    // If StructTy is an opaque type, it should have at least <cpyLen> bytes,
>>     +    // as implified by the copy-instruction.
>>     +    uint64_t destSize = StructTy->isSized() ?
>>     +                        TD->getTypeAllocSize(StructTy) : cpyLen;
>>          if (destSize < srcSize)
>>            return false;
>>
>>
>> Why is it safe to assume StructTy is at least cpyLen bytes?
> If not, why is it possible copying cpyLen byte from (part of) src to Dest?

unfortunately you can't assume that the original memcpy is executed, because the
call might not return:

   call @func(..., src, ...)
^ might throw an exception or exit
   memcpy(dest, src, ...)

Thus you can't assume that writing cpyLen bytes to dest is automatically safe.

   memcpy(dest, src, ...)
^ moving the memcpy before the call requires knowing the write to dest is safe
   call @func(..., dest, ...)

I think you should just bail out if !StructTy->isSized().

Ciao, Duncan.

>
>> And if it is safe, why is this check necessary at all?
>>
> I guess you confuse cpyLen with SrcLen.
> I asked the same question when I read the code. After the 2nd thought, I think
> it is necessary.
> You never know how the callee access the Src, it could access the last byte (the
> SrcSize-th byte) of the object
> corresponding to the Src, and cpyLen < SrcSize.
>
>
>
>
>
>
> _______________________________________________
> 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