[LLVMdev] Question about intrinsic function llvm.objectsize

Nuno Lopes nunoplopes at sapo.pt
Wed Feb 27 02:05:15 PST 2013


Hi,

Regarding the definition of object for @llvm.objectsize, it is  
identical to gcc's __builtin_object_size().  So it's not wrong; it's  
just the way it was defined to be.

Regarding the BasicAA's usage of these functions, I'm unsure.  It  
seems to me that isObjectSmallerThan() also expects the same  
definition, but I didn't review the code carefully.
When you do a load from a certain memory address, basicAA is  
interested to know if that load will overflow the buffer bounds, which  
means that no aliasing can occur (or it's an UB operation).
Therefore I don't think basicAA cares about the size of the whole  
object, but just the remaining part of it (size-offset).  But again, I  
could be wrong here.

Nuno


Quoting Shuxin Yang <shuxin.llvm at gmail.com>:

> Hi,
>
>   In the following instruction sequence, llvm.objectsize.i64(p)  
> returns 6 (the entire *.ll is attached to the mail).
> Is this correct? Shouldn't the "object" refer to the entire block of  
> memory being allocated?
>
>   (char*) p = malloc(56)
>   llvm.objectisize.i32(p+50);
>
> Thanks
> Shuxin
>
>
>
>   This question is related to PR14988 (failure in bootstrap build  
> with LTO). Part of the reason is that
> the compiler interpret the pretty vague team "object" in different  
> ways -- the "object" suggested by
> line 359 @ figure 1 is just a part of the "object" implied by Figure 2.
>
>   I try to fix the problem PR14988 by replacing line 359 with "Size  
> = Offset.getZextValue()"; It does fix the problem.
> However, I'm wondering in what situations the Offset != 0. So I put  
> an assertion right before line 359,
> saying "assert(Offset != 0)". It catches two cases in SingleSource  
> test suite. I investigate one of them,
> the assertion is triggered when the llvm::getObjectSize() is called  
> by instcombine (instead of alias analyizer)
> in an attempt to replace llvm.objectsize() with a constant. I think  
> the way  llvm::getObjectSize() interpret "object" is wrong.
>
>
> Figure 1
> cat -n lib/Analysis/MemoryBuiltins.cpp
>   344 bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size,  
> const DataLayout *TD,
>   345                          const TargetLibraryInfo *TLI, bool  
> RoundToAlign) {
>   346   if (!TD)
>   347     return false;
>   348
>   349   ObjectSizeOffsetVisitor Visitor(TD, TLI, Ptr->getContext(),  
> RoundToAlign);
>   350   SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
>   351   if (!Visitor.bothKnown(Data))
>   352     return false;
>   353
>   354   APInt ObjSize = Data.first, Offset = Data.second;
>   355   // check for overflow
>   356   if (Offset.slt(0) || ObjSize.ult(Offset))
>   357     Size = 0;
>   358   else
>   359     Size = (ObjSize - Offset).getZExtValue(); ??? What the  
> hack is "object"??????
>   360   return true;
>   361 }
>
> Figure 2
> cat -n lib/Analysis/BasicAliasAnalysis.cpp
> 1205   // If the size of one access is larger than the entire object  
> on the other
> 1206   // side, then we know such behavior is undefined and can  
> assume no alias.
> 1207   if (TD)
> 1208     if ((V1Size != UnknownSize && isObjectSmallerThan(O2,  
> V1Size, *TD, *TLI)) ||
> 1209         (V2Size != UnknownSize && isObjectSmallerThan(O1,  
> V2Size, *TD, *TLI)))
> 1210       return NoAlias;



More information about the llvm-dev mailing list