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

Shuxin Yang shuxin.llvm at gmail.com
Fri Jun 7 21:07:01 PDT 2013


On 6/7/13 8:43 PM, Duncan Sands wrote:
> 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.
>
Yes, you are right.  Thank you for pointing out this tricky case.
I will change the code that way.





More information about the llvm-commits mailing list