[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